package betandregret.tests;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

import java.util.Calendar;

import org.junit.Test;

import betandregret.exceptions.RegretException;
import betandregret.interfaces.IBetAndRegret.Systemereignis;

/**
 * Tests der Systemoperation spielEintragen(...)
 * 
 */
public class MitarbeiterSpielEintragenTest extends AbstractBetAndRegretTest {

	private Calendar[] calendar;
	private int[] sportarten;
	private int[] basketballTeams;
	private int[] rollstuhlBasketballTeams;

	/**
	 * Diese Methode erzeugt einen Datensatz, der fuer die folgenden Tests zur
	 * Verfuegung steht.
	 */
	private void calendarSportartenTeamsAnlegen() {
		calendar = new Calendar[4];
		calendar[0] = Calendar.getInstance();
		calendar[0].set(2015, 1, 5, 18, 0);
		calendar[1] = Calendar.getInstance();
		calendar[1].set(2015, 1, 6, 20, 0);
		calendar[2] = Calendar.getInstance();
		calendar[2].set(2014, 1, 7, 20, 0);
		calendar[3] = Calendar.getInstance();
		calendar[3].set(2012, 1, 20, 23, 0);

		betAndRegretSystem.setDatum(calendar[3]);

		sportarten = new int[2];
		sportarten[0] = mitarbeiterBoundary.sportartEintragen("Basketball", 80);
		sportarten[1] = mitarbeiterBoundary.sportartEintragen(
				"Rollstuhlbasketball", 90);

		basketballTeams = new int[4];
		basketballTeams[0] = mitarbeiterBoundary.teamEintragen(
				"Venomous Monkeys", sportarten[0]);
		basketballTeams[1] = mitarbeiterBoundary.teamEintragen(
				"Banzai Bullets", sportarten[0]);
		basketballTeams[2] = mitarbeiterBoundary.teamEintragen(
				"Sole Survivors", sportarten[0]);
		basketballTeams[3] = mitarbeiterBoundary.teamEintragen("Average Joes",
				sportarten[0]);

		rollstuhlBasketballTeams = new int[4];
		rollstuhlBasketballTeams[0] = mitarbeiterBoundary.teamEintragen(
				"Mighty Tigers", sportarten[1]);
		rollstuhlBasketballTeams[1] = mitarbeiterBoundary.teamEintragen(
				"Silent Kamikaze Pilots", sportarten[1]);
		rollstuhlBasketballTeams[2] = mitarbeiterBoundary.teamEintragen(
				"Spinning Piledrivers", sportarten[1]);
		rollstuhlBasketballTeams[3] = mitarbeiterBoundary.teamEintragen(
				"The FlyBallers", sportarten[1]);
	}

	/**
	 * Drei Spiele werden erfolgreich eingetragen. Sollte Ihr System
	 * fehlerhafter Weise eine Exception werfen, fuehrt dies zu einem fail des
	 * Tests. zudem wird ein Spielplan erzeugt und ausgeben
	 */
	@Test
	public void spielEintragenErfolgreich_1_0_0() {

		String testfall = "1.0.0 Spiel anlegen erfolgreich: drei Spiel";

		calendarSportartenTeamsAnlegen();

		int[] spielIDs = new int[4];
		
		try {
			spielIDs[0] = mitarbeiterBoundary.spielEintragen(
					basketballTeams[0], basketballTeams[1], calendar[0], 80);
			spielIDs[1] = mitarbeiterBoundary.spielEintragen(
					rollstuhlBasketballTeams[0], rollstuhlBasketballTeams[1],
					calendar[1], 100);
			spielIDs[2] = mitarbeiterBoundary.spielEintragen(
					rollstuhlBasketballTeams[0], rollstuhlBasketballTeams[2],
					calendar[2], 50);

			System.out.println("=====");
			System.out.println(testfall + "\n");
			System.out.println(mitarbeiterBoundary.spielplanErstellen());
			System.out.println("=====\n\n");

		} catch (RegretException e) {
			fail(testfall + " " + e);
		}
	}

	/**
	 * Drei Spiele werden erfolgreich eingetragen,sowie ein Endergebnis und 3
	 * wetten. Sollte Ihr System fehlerhafter Weise eine Exception werfen,
	 * fuehrt dies zu einem fail des Tests. zudem wird ein Spielplan erzeugt und
	 * ausgeben
	 */
	@Test
	public void spielEintragenErfolgreich_1_0_1() {
		int kundeID, kunde2ID;
		String testfall = "1.0.1 Spiel anlegen erfolgreich: drei Spiel";

		calendarSportartenTeamsAnlegen();

		int[] spielIDs = new int[4];
		
		try {
			spielIDs[0] = mitarbeiterBoundary.spielEintragen(
					basketballTeams[0], basketballTeams[1], calendar[0], 80);
			spielIDs[1] = mitarbeiterBoundary.spielEintragen(
					rollstuhlBasketballTeams[0], rollstuhlBasketballTeams[1],
					calendar[1], 100);
			spielIDs[2] = mitarbeiterBoundary.spielEintragen(
					rollstuhlBasketballTeams[0], rollstuhlBasketballTeams[2],
					calendar[2], 50);
			kundeID = this.kundenBoundary.kundeEintragen("Hans Bernd");
			kunde2ID = this.kundenBoundary.kundeEintragen("R2D2");
			this.kundenBoundary.wettePlatzieren(kundeID, 100, spielIDs[1],
					rollstuhlBasketballTeams[1]);
			this.kundenBoundary.wettePlatzieren(kunde2ID, 420, spielIDs[1],
					rollstuhlBasketballTeams[0]);

			this.kundenBoundary.wettePlatzieren(kundeID, 100, spielIDs[2],
					rollstuhlBasketballTeams[0]);

			Calendar spater = Calendar.getInstance();
			spater.set(2017, 1, 5, 11, 0);
			this.betAndRegretSystem.setDatum(spater);
			this.mitarbeiterBoundary.ergebnisEintragen(
					rollstuhlBasketballTeams[1], spielIDs[1], "1:1");

			System.out.println("=====");
			System.out.println(testfall + "\n");
			System.out.println(mitarbeiterBoundary.spielplanErstellen());
			System.out.println("=====\n\n");

		} catch (RegretException e) {
			fail(testfall + " " + e);
		}
	}

	/**
	 * Hier wird ein Fehlerfall getestet. Ihr System sollte auf die Dateneingabe
	 * mit einer entsprechenden Exception reagieren und in den catch Block
	 * springen. Sollte die Systemoperation dennoch ein Spiel eintragen, fuehrt
	 * das zum fail des Tests.
	 */
	@Test
	public void spielEintragenFehler_1_1() {
		String testfall = "1.1 Spiel eintragen fehlerhaft: Sportarten unterschiedlich";

		calendarSportartenTeamsAnlegen();

		int[] spielIDs = new int[3];
		
		try {
			spielIDs[0] = mitarbeiterBoundary.spielEintragen(
					basketballTeams[0], basketballTeams[1], calendar[0], 80);
			spielIDs[1] = mitarbeiterBoundary.spielEintragen(
					rollstuhlBasketballTeams[0], rollstuhlBasketballTeams[1],
					calendar[1], 100);
			spielIDs[2] = mitarbeiterBoundary.spielEintragen(
					rollstuhlBasketballTeams[0], rollstuhlBasketballTeams[2],
					calendar[0], 50);

			mitarbeiterBoundary.spielEintragen(basketballTeams[0],
					rollstuhlBasketballTeams[1], calendar[2], 50);
			fail(testfall);
		} catch (RegretException e) {
			assertEquals(testfall,
					Systemereignis.SPORTARTEN_DER_TEAMS_VERSCHIEDEN,
					e.getSystemereignis());

		}
	}

	/**
	 * Hier wird ein Fehlerfall(Startzeit liegt nicht in der Zukunft) getest.
	 * erfolgreich wenn Exception geworfen mit passendem Systemereigniss
	 */
	@Test
	public void spielEintragen_Fehler_1_2() {
		String testfall = "1.2 Spieleintragen fehlerhaft: STARTZEIT_LIEGT_NICHT_IN_DER_ZUKUNFT";
		calendarSportartenTeamsAnlegen();
		Calendar vergangenheit = Calendar.getInstance();
		vergangenheit.set(1989, 1, 5, 18, 0);
		
		try {
			mitarbeiterBoundary.spielEintragen(basketballTeams[0],
					basketballTeams[1], vergangenheit, 80);
			fail(testfall);
		} catch (RegretException e) {
			assertEquals(testfall,
					Systemereignis.STARTZEIT_LIEGT_NICHT_IN_DER_ZUKUNFT,
					e.getSystemereignis());
		}

	}

	/**
	 * Hier wird ein Fehlerfall(Team Spielt bereits(gleiche Startzeit) getest.
	 * erfolgreich wenn Exception geworfen mit passendem Systemereigniss
	 */
	@Test
	public void spielEintragen_Fehler1_3_1() {
		String testfall = "1.3 Spieleintragen fehlerhaft: TEAM_SPIELT_BEREITS (gleiche Startzeit)";
		calendarSportartenTeamsAnlegen();

		try {
			mitarbeiterBoundary.spielEintragen(basketballTeams[0],
					basketballTeams[1], calendar[0], 80);
			mitarbeiterBoundary.spielEintragen(basketballTeams[0],
					basketballTeams[3], calendar[0], 80);
			fail(testfall);
		} catch (RegretException e) {
			assertEquals(testfall, Systemereignis.TEAM_SPIELT_BEREITS,
					e.getSystemereignis());

		}
	}

	/**
	 * Hier wird ein Fehlerfall(Team Spielt bereits(gleicher Zeitraum vorher)
	 * getest. erfolgreich wenn Exception geworfen mit passendem Systemereigniss
	 */
	@Test
	public void spielEintragen_Fehler1_3_2() {
		String testfall = "1.3.2 Spieleintragen fehlerhaft: TEAM_SPIELT_BEREITS (Startzeit ungleich, an spiel vorher beteiligt)";
		calendarSportartenTeamsAnlegen();
		Calendar spaeter = Calendar.getInstance();
		spaeter.set(2015, 1, 6, 21, 0);

		try {
			mitarbeiterBoundary.spielEintragen(basketballTeams[0],
					basketballTeams[1], calendar[1], 80);
			mitarbeiterBoundary.spielEintragen(basketballTeams[0],
					basketballTeams[3], spaeter, 80);
			fail(testfall);
		} catch (RegretException e) {
			assertEquals(testfall, Systemereignis.TEAM_SPIELT_BEREITS,
					e.getSystemereignis());

		}
	}

	/**
	 * Hier wird ein Fehlerfall(Team Spielt bereits(gleicher Zeitraum nacher)
	 * getest. erfolgreich wenn Exception geworfen mit passendem Systemereigniss
	 */
	@Test
	public void spielEintragen_Fehler1_3_3() {
		String testfall = "1.3.3 Spieleintragen fehlerhaft: TEAM_SPIELT_BEREITS (Startzeit ungleich, anspiel nacher beteiligt)";
		calendarSportartenTeamsAnlegen();
		Calendar frueher = Calendar.getInstance();
		frueher.set(2015, 1, 6, 19, 0);

		try {
			mitarbeiterBoundary.spielEintragen(basketballTeams[0],
					basketballTeams[1], calendar[1], 80);
			mitarbeiterBoundary.spielEintragen(basketballTeams[0],
					basketballTeams[3], frueher, 80);
			fail(testfall);
		} catch (RegretException e) {
			assertEquals(testfall, Systemereignis.TEAM_SPIELT_BEREITS,
					e.getSystemereignis());

		}
	}

}
